图标快捷菜单
iOS 9 新增了桌面图标快捷菜单的功能(Home Screen Quick Actions)。用户按压桌面图标能弹出几个选项,进行某些快捷操作。
iOS 9 下每个应用最多能显示4个桌面快捷选项。系统优先显示静态快捷选项,从上往下。如果未超出限制,且应用有定义动态快捷选项,显示动态快捷选项。
静态快捷选项
在应用的 Info.plist 顶层中新增 UIApplicationShortcutItems 数组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| <key>UIApplicationShortcutItems</key> <array> <dict> <key>UIApplicationShortcutItemIconType</key> <string>UIApplicationShortcutIconTypeSearch</string> <key>UIApplicationShortcutItemSubtitle</key> <string>shortcutSubtitle1</string> <key>UIApplicationShortcutItemTitle</key> <string>shortcutTitle1</string> <key>UIApplicationShortcutItemType</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER).First</string> <key>UIApplicationShortcutItemUserInfo</key> <dict> <key>firstShorcutKey1</key> <string>firstShortcutKeyValue1</string> </dict> </dict> <dict> <key>UIApplicationShortcutItemIconType</key> <string>UIApplicationShortcutIconTypeShare</string> <key>UIApplicationShortcutItemSubtitle</key> <string>shortcutSubtitle2</string> <key>UIApplicationShortcutItemTitle</key> <string>shortcutTitle2</string> <key>UIApplicationShortcutItemType</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER).Second</string> <key>UIApplicationShortcutItemUserInfo</key> <dict> <key>secondShortcutKey1</key> <string>secondShortcutValue1</string> </dict> </dict> </array>
|
静态定义快速在运行时常用的key:
key | 说明
— | —
UIApplicationShortcutItemType | (必须使用) 用来区分与其他快速选项的分类
UIApplicationShortcutItemTitle | (必须使用) 快速选项显示的标题
UIApplicationShortcutItemSubtitle | 快速选项显示的子标题
UIApplicationShortcutItemIconType | 图片类型由系统提供
UIApplicationShortcutItemIconFile | 自定义的图标
UIApplicationShortcutItemUserInfo | 附加信息
动态快捷选项
指定[UIApplication sharedApplication].shortcutItems。
动态快捷选项必须启动应用且设置shortcutItems后,才能生效。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| - (void)setupApplicationShortcutItems { UIApplicationShortcutIcon *homeIcon = [UIApplicationShortcutIcon iconWithType:UIApplicationShortcutIconTypeCompose]; NSDictionary *userInfo1 = @{@"key":@"home"}; NSDictionary *userInfo2 = @{@"key":@"message"}; UIMutableApplicationShortcutItem *homeShortcutItem = [[UIMutableApplicationShortcutItem alloc] initWithType:@"home" localizedTitle:@"主页" localizedSubtitle:@"跳转主页" icon:homeIcon userInfo:userInfo1]; UIMutableApplicationShortcutItem *messageShortcutItem = [[UIMutableApplicationShortcutItem alloc] initWithType:@"message" localizedTitle:@"消息" localizedSubtitle:@"跳转消息" icon:nil userInfo:userInfo2]; NSArray *items = @[homeShortcutItem,messageShortcutItem]; [UIApplication sharedApplication].shortcutItems = items; }
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self setupApplicationShortcutItems]; ... }
|
快捷选项操作
在AppDelegate.m文件中添加
application:performActionForShortcutItem:completionHandler:
代理方法,根据UIApplicationShortcutItem的type属性和之前在info.plist设置UIApplicationShortcutItemType对应的在值来判断,用户点击的是哪个快速选项。这个方法在接近激活应用时就会调用,除了
-application:willFinishLaunchingWithOptions:
or
-application:didFinishLaunchingWithOptions
returns NO.
这种情况。
在-application:didFinishLaunchingWithOptions
中可以通过UIApplicationLaunchOptionsShortcutItemKey键来获取当前接收快速选项的UIApplicationShortcutItem对象,来处理用户的意图。
Peek 和 Pop
这个功能是一套全新的用户交互机制,在使用3D Touch时,ViewController中会有如下三个交互阶段:
- 提示用户这里有3D Touch的交互,会使交互控件周围模糊
- 继续深按,会出现预览视图
- 通过视图上的交互控件进行进一步交互
peek 和 pop 的核心主要是 iOS9 上新增的以下几个代理方法:
- registerForPreviewingWithDelegate:sourceView:
- previewingContext:viewControllerForLocation:
- previewingContext:commitViewController:
- previewActionItems
下面结合几段代码看看 peek 和 pop 的用法。
假设现在有两个 ViewController,MasterViewController 和 DetailViewController,MasterViewController 上有一个 TableView,点击上面的 Cell 进入 DetailViewController。
首先,MasterViewController 需要调用注册接口以支持3D touch,指定接收3D touch 事件的 view 和处理 peek 和 pop 的代理 。
1 2 3 4 5 6
| if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) { [self registerForPreviewingWithDelegate:self sourceView:self.view]; }
|
如果考虑得周全一点,应该在识别到用户关闭了 3D touch 时,调用unregisterForPreviewingWithContext:注销 3D touch。
接下来,在 MasterViewController 上需要实现以下代理。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| - (void)previewingContext:(id<UIViewControllerPreviewing>)previewingContext commitViewController:(UIViewController *)viewControllerToCommit { [self showViewController:viewControllerToCommit sender:self]; }
- (UIViewController *)previewingContext:(id<UIViewControllerPreviewing>)previewingContext viewControllerForLocation:(CGPoint)location { NSIndexPath *indexPath = [_tableView indexPathForRowAtPoint:location]; UITableViewCell *cell = [_tableView cellForRowAtIndexPath:indexPath]; if (cell == nil) return nil; DetailViewController *detailViewController = [DetailViewController new]; [detailViewControler loadDataFromModel:self.modelList[indexPath.row]]; [previewingContext setSourceRect:cell.frame]; [detailViewController setPreferredContentSize = CGSizeMake(0, previewDetail.preferredHeight)]; return cv; }
|
通常,在弹出预览窗口后,可以上滑,弹出菜单,进行某些快捷操作。前提是预览的 ViewController 实现了-previewActionItems,指定了peek 快捷操作。如果没实现该代理,则没有快捷菜单,弹出预览后滑动没有效果,放开就消失了。
快捷菜单可以通过 UIPreiveActionGroup 组织成多个层级,详情见代码。
以下是 DetailViewController 的 previewActionItems 示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| - (NSArray<id<UIPreviewActionItem>> *)previewActionItems { UIPreviewAction *action1 = [UIPreviewAction actionWithTitle:@"action1" style:UIPreviewActionStyleDefault handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) { NSLog(@"preview action 1"); }]; UIPreviewAction *action2 = [UIPreviewAction actionWithTitle:@"action2" style:UIPreviewActionStyleDestructive handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) { NSLog(@"preview action 2"); }]; UIPreviewAction *action3 = [UIPreviewAction actionWithTitle:@"action3" style:UIPreviewActionStyleSelected handler:^(UIPreviewAction * _Nonnull action, UIViewController * _Nonnull previewViewController) { NSLog(@"preview action 3"); }]; UIPreviewActionGroup *actionGroup = [UIPreviewActionGroup actionGroupWithTitle:@"action group" style:UIPreviewActionStyleDefault actions:@[action2, action3] ]; return @[action1, actionGroup]; }
|
UITouch
UITouch 新增两个用于 3d touch 的字段: force 和 maximumPossibleForce。这些属性可以让你侦测并响应APP接收的UIEvent触摸压力。